package processors;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import util.FileUtil;
import util.StringUtil;

public class WordsSplitProcessor {
	private Map<String, Integer> dictionary;
	
	public WordsSplitProcessor(){
		dictionary = loadinDictionary("WebContent/FILES/DICTIONARY.txt");
	}
	public ArrayList<String> process(ArrayList<String> contents) {
		ArrayList<String> filteredcontents = new ArrayList<String>();
		Pattern pattern = Pattern.compile("[\\d]+");
		for(String content : contents){
			ArrayList<String> filteredWords = new ArrayList<String>();
			ArrayList<String> words = StringUtil.lexicalAnalyze(content);
			for(String word : words){
				if(pattern.matcher(word).find()){
					String[] strs = word.split("((?<=[0-9])(?=[a-z]))|((?=[0-9])(?<=[a-z]))");
					for(String str : strs){
						Matcher m = pattern.matcher(str);
						if(m.matches()){
							filteredWords.add(str);
						}else{
							analyze(filteredWords, str);
						}
					}
				}else{
					analyze(filteredWords, word);
				}
			}
			String newcontent = StringUtil.listToString(filteredWords);
			filteredcontents.add(newcontent);
		}
		return filteredcontents;
	}

	private void analyze(ArrayList<String> filteredWords, String word){
		if(word.length() <= 6){
			filteredWords.add(word);
		}
		else{
			ArrayList<String> result = split(word);
			for(int i = 0; i < result.size(); i++)
				filteredWords.add(result.get(i));
		}
	}
	
	private ArrayList<String> split(String word){
		ArrayList<String> resultOfDirection1 = scan(word, 0);
		ArrayList<String> resultOfDirection2 = scan(word, 1);
		ArrayList<String> returnList = new ArrayList<String>();
		if(resultOfDirection1.size() >= resultOfDirection2.size()){
			for(int i = 0; i < resultOfDirection2.size(); i++)
				returnList.add(resultOfDirection2.get(i));
		}else{
			for(int i = resultOfDirection1.size() - 1; i >= 0; i--)
				returnList.add(resultOfDirection1.get(i));
		}
		return returnList;
	}
	
	public ArrayList<String> scan(String word, int direction){
		ArrayList<String> result = new ArrayList<String>();
		if(direction == 0){
			int wordLength = word.length();
			int endIndex = wordLength;
			int beginIndex = wordLength - 1;
			ArrayList<String> successWordsList = new ArrayList<String>();
			while(endIndex > 0){
				if(beginIndex == -1){
					String longestWord = getLongestWord(successWordsList);
					successWordsList = new ArrayList<String>();
					if(longestWord == null){
						result.add(word.substring(beginIndex+1, endIndex));
						break;
					}
					else {
						result.add(longestWord);
						endIndex = endIndex - longestWord.length();
						beginIndex = endIndex - 1;
					}
				}else{
					String subword = word.substring(beginIndex, endIndex);
					if(dictionary.containsKey(subword)){
						successWordsList.add(subword);
					}
					beginIndex--;
				}
			}
		}else{
			int wordLength = word.length();
			int endIndex = 1;
			int beginIndex = 0;
			ArrayList<String> successWordsList = new ArrayList<String>();
			while(beginIndex < wordLength){
				if(endIndex > wordLength){
					String longestWord = getLongestWord(successWordsList);
					successWordsList = new ArrayList<String>();
					if(longestWord == null){
						result.add(word.substring(beginIndex, endIndex-1));
						break;
					}
					else {
						result.add(longestWord);
						beginIndex = beginIndex + longestWord.length();
						endIndex = beginIndex + 1;
					}
				}else{
					String subword = word.substring(beginIndex, endIndex);
					if(dictionary.containsKey(subword)){
						successWordsList.add(subword);
					}
					endIndex++;
				}
			}
		}
		return result;
	}
	private String getLongestWord(ArrayList<String> successWordsList) {
		String longestWord = "";
		for(String word : successWordsList){
			if(word.length() > longestWord.length())
				longestWord = word;
		}
		if(longestWord.equals(""))
			return null;
		return longestWord;
		
	}
	
	private Map<String, Integer> loadinDictionary(String fileName) {
		ArrayList<String> dictionaryWords = FileUtil.loadinFile(fileName);
		Map<String, Integer> dictionary = new HashMap<String,Integer>();
		for(String word : dictionaryWords){
			dictionary.put(word.toLowerCase(),1);
		}
		return dictionary;
	}

}
